import java.io.File;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;

import game.GamePlayer;
import game.Params;
import game.Tournament;
import breakthrough.*;

public class Trainer {

	private static final char SEP = File.separatorChar;
	
	static Params tournamentParams = new Params("config" + SEP + "tournament.txt");
	static int NUM_CLIENTS1 = tournamentParams.integer("NUMCLIENTS");
	static int[][][] summary;
	
	public static void main(String[] args)
	{
		GLaDOSBreakthroughPlayer p = new GLaDOSBreakthroughPlayer("Player",new Heuristic());
		GLaDOSBreakthroughPlayer best = (GLaDOSBreakthroughPlayer)tourn(p);
		boolean again = true;
//		while(again)	{
		for (int i = 0 ; i < 1 ; i++)	{	best = (GLaDOSBreakthroughPlayer)tourn(best);
			GLaDOSBreakthroughPlayer best2 = (GLaDOSBreakthroughPlayer)tourn(best);
			if (best2 != best) best = best2;
			else again = false;
			System.out.println(best.nickname + " is the winner!");
			sleep(100);
		}
		System.out.println("FINAL WINNER = " + best.nickname);
		System.out.println("Heuristics : ");
		
	}
	
	public static void sleep(long time)
	{
		try{
			Thread.sleep(time);
		}catch(InterruptedException e)	{}
	}
	
	public static GamePlayer tourn(GamePlayer best)	{
		TournamentThread t = new TournamentThread();
		t.start();
		GLaDOSBreakthroughPlayer currBest = (GLaDOSBreakthroughPlayer) best;
		ArrayList<GamePlayer> listOfPlayers = new ArrayList<GamePlayer>();
		for (int i = 0 ; i < NUM_CLIENTS1 ; i++)	{
			sleep(100);
			GamePlayer p;
			if (currBest == null || i != 0)	{
				SecureRandom random = new SecureRandom();
				p = new GLaDOSBreakthroughPlayer(new BigInteger(50,random).toString(32) +""+ i,new Heuristic());
//				p = new GreedyBreakthroughPlayer(new BigInteger(50,random).toString(32) +""+ i);
			}
			else p = currBest;
			listOfPlayers.add(p);
			new PlayerThread(p).start();
		}
		try{
			t.join();
		}catch(InterruptedException e)	{
			
		}
		int[] num_wins = new int[NUM_CLIENTS1];
		for (int i = 0 ; i < NUM_CLIENTS1 ; i++)	{
			for (int j = 0 ; j < NUM_CLIENTS1 ; j++)	{
				num_wins[i] += summary[i][j][0];
				num_wins[j] += summary[i][j][1];
			}
			
		}
		PlayerWins[] playerWin = new PlayerWins[NUM_CLIENTS1];
		for (int i = 0 ; i < NUM_CLIENTS1 ; i++)
			playerWin[i] = new PlayerWins(listOfPlayers.get(i),num_wins[i]);
		Arrays.sort(playerWin);
		
		return playerWin[0].player;
	}
	
	private static class PlayerThread extends Thread	{
		GamePlayer player;
		public PlayerThread(GamePlayer player)	{
			super();
			this.player = player;
		}
		
		@Override
		public void run() {
			String[] args = {};
			player.compete(args);
			
		}
	}
	
	private static class TournamentThread extends Thread	{

		public TournamentThread()	{
			Tournament.tournamentParams = new Params("config" + SEP + "tournament.txt");
			Tournament.gameParams = new Params("config" + SEP + "Breakthrough.txt");		
			System.out.printf("Starting %s tournament%n", "Breakthrough");
			System.out.printf("%d clients%n", Tournament.tournamentParams.integer("NUMCLIENTS"));
			System.out.printf("%d clients%n", Tournament.tournamentParams.integer("NUMCLIENTS2"));
		}
		
		@Override
		public void run() {
			summary = Tournament.launchTournament(new BreakthroughState(), new BreakthroughMove());
		
		}	
	}
	
	private static class PlayerWins implements Comparable<PlayerWins>	{
		public GamePlayer player;
		public int wins;
		
		public PlayerWins(GamePlayer player, int wins)	{
			this.player = player;
			this.wins = wins;
		}

		@Override
		public int compareTo(PlayerWins arg0) {
			
			return arg0.wins-wins;
		}
	}
}

